﻿

namespace Acoris.Foundation
{
    using System.Collections.Generic;
    using System.Diagnostics;

    /// <summary>
    /// 表示长度
    /// </summary>
    [DebuggerDisplay("width:{Width},height:{Height}")]    
    public struct Size:IEqualityComparer<Size>
    {
        /// <summary>
        /// 初始化指定的长度
        /// </summary>
        /// <param name="width">指定的宽度</param>
        /// <param name="height">指定的高度</param>
        public Size(float width,float height)
        {
            Width = width;
            Height = height;
        }

        #region Method

        /// <summary>
        /// 合并指定区域大小
        /// </summary>
        /// <param name="size">要合并的大小</param>
        /// <returns>返回一个表示新的区域大小的值</returns>
        public Size Union(Size size)
        {
            return new Size
            {
                Height = this.Height + size.Height,
                Width = this.Width + size.Width
            };
        }

        /// <summary>
        /// 移除指定区域大小
        /// </summary>
        /// <param name="size">指定的大小</param>
        /// <returns>返回一个移除指定区域大小的值</returns>
        public Size Except(Size size)
        {
            return new Size
            {
                Height = this.Height - size.Height,
                Width = this.Width - size.Width
            };
        }

        #endregion

        #region Property

        /// <summary>
        /// 获取或设置长度
        /// </summary>
        public float Width { get; set; }

        /// <summary>
        /// 获取或设置高度
        /// </summary>
        public float Height { get; set; }

        #endregion

        #region Override

        /// <summary>
        /// 获取与当前对象等价的字符串形式
        /// </summary>
        /// <returns>返回与当前对象等价的字符串形式</returns>
        public override string ToString()
        {
            return $"width:{Width},height:{Height}";
        }

        /// <summary>
        /// 获取当前对象与指定对象之间的等价性
        /// </summary>
        /// <param name="obj">指定要比较的对象</param>
        /// <returns>如果两个对象之间等价则返回true，否则返回false</returns>
        public override bool Equals(object obj)
        {
            if(obj is Size size)
            {
                return size.Height == this.Height && size.Width == this.Width;
            }
            return false;
        }

        /// <summary>
        /// 获取当前对象的哈希值
        /// </summary>
        /// <returns>返回当前对象的哈希值</returns>
        public override int GetHashCode()
        {
            return this.Height.GetHashCode() ^ this.Width.GetHashCode();
        }
        #endregion

        #region IEqualityComparer<Size>接口成员

        public bool Equals(Size x, Size y)
        {
            return x == y;
        }

        public int GetHashCode(Size obj)
        {
            return obj.GetHashCode();
        }

        #endregion

        #region operator == / !=

        public static bool operator !=(Size x,Size y)
        {
            return x.Width != y.Width || x.Height != y.Height;
        }

        public static bool operator ==(Size x,Size y)
        {
            return x.Width == y.Width && x.Height == y.Height;
        }

        #endregion

        #region operator +/-

        public static Size operator +(Size x,Size y)
        {
            return new Size
            {
                Height = x.Height + y.Height,
                Width = x.Width + y.Width
            };
        }

        public static Size operator -(Size x,Size y)
        {
            return new Size
            {
                Height = x.Height - y.Height,
                Width = x.Width - y.Width
            };
        }

        #endregion

        #region operator *
        public static Size operator *(Size size,int value)
        {
            return new Size { Height = size.Height * value, Width = size.Width * value };
        }

        public static Size operator *(Size size,float value)
        {
            return new Size { Height = size.Height * value, Width = size.Width * value };
        }

        public static Size operator *(Size size,double value)
        {
            return new Size { Height = (float)(size.Height * value), Width = (float)(size.Width * value) };
        }
        #endregion

        #region operator /
        public static Size operator /(Size size, int value)
        {
            return new Size { Height = size.Height / value, Width = size.Width / value };
        }

        public static Size operator /(Size size, float value)
        {
            return new Size { Height = size.Height / value, Width = size.Width / value };
        }

        public static Size operator /(Size size, double value)
        {
            return new Size { Height = (float)(size.Height / value), Width = (float)(size.Width / value) };
        }

        #endregion
    }
}
